package com.class1group3.demo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DataAccessException;

@Component
public class AuthorSummaryInitializer implements CommandLineRunner {

    private static final Logger log = LoggerFactory.getLogger(AuthorSummaryInitializer.class);

    private final JdbcTemplate jdbcTemplate;

    @Autowired
    public AuthorSummaryInitializer(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    @Override
    public void run(String... args) {
        try {
            log.info("开始初始化作者汇总表...");

            // 设置Hive优化参数
            setHiveOptimizationParams();

            // 创建作者汇总表
            createAuthorSummaryTable();

            // 执行数据插入
            insertAuthorSummaryData();

            log.info("作者汇总表初始化成功");
        } catch (DataAccessException e) {
            handleInitializationError(e);
        }
    }

    private void setHiveOptimizationParams() {
        try {
            jdbcTemplate.execute("SET hive.exec.dynamic.partition=true");
            jdbcTemplate.execute("SET hive.exec.dynamic.partition.mode=nonstrict");
            jdbcTemplate.execute("SET hive.vectorized.execution.enabled=true");
            jdbcTemplate.execute("SET hive.map.aggr=true");
            jdbcTemplate.execute("SET hive.groupby.skewindata=true");
            log.info("Hive优化参数设置成功");
        } catch (DataAccessException e) {
            log.warn("设置Hive优化参数失败，继续执行: {}", e.getMessage());
        }
    }

    private void createAuthorSummaryTable() {
        String createTableSql = "CREATE TABLE IF NOT EXISTS author_summary (\n" +
                "    authors STRING COMMENT '作者名称',\n" +
                "    avg_rating DECIMAL(3,2) COMMENT '平均评分',\n" +
                "    book_count INT COMMENT '书籍数量'\n" +
                ") STORED AS ORC\n" +
                "TBLPROPERTIES (\n" +
                "    'orc.compress'='SNAPPY',\n" +
                "    'transactional'='false'\n" +
                ")";

        jdbcTemplate.execute(createTableSql);
        log.info("作者汇总表创建/验证成功");
    }

    private void insertAuthorSummaryData() {
        String insertSql = "INSERT OVERWRITE TABLE author_summary\n" +
                "SELECT \n" +
                "    authors,\n" +
                "    ROUND(AVG(\n" +
                "        CASE \n" +
                "            WHEN rating BETWEEN 0 AND 5 THEN CAST(rating AS DECIMAL(3,2))\n" +
                "            ELSE NULL \n" +  // 处理异常值
                "        END\n" +
                "    ), 2) AS avg_rating,\n" +
                "    COUNT(*) AS book_count\n" +
                "FROM books\n" +
                "WHERE authors IS NOT NULL \n" +
                "  AND TRIM(authors) != ''\n" +
                "  AND LENGTH(authors) <= 500  -- 防止超长字符串\n" +
                "GROUP BY authors\n" +
                "ORDER BY book_count DESC";

        jdbcTemplate.execute(insertSql);
        log.info("作者汇总数据插入成功");
    }

    private void handleInitializationError(DataAccessException e) {
        log.error("作者汇总表初始化失败", e);

        if (e.getCause() != null) {
            String errorMsg = e.getCause().getMessage();

            if (errorMsg.contains("Permission denied")) {
                log.error("=== HDFS权限问题 ===");
                log.error("请执行以下命令修复权限：");
                log.error("hdfs dfs -chmod -R 775 /user/hive/warehouse/author_summary");
                log.error("或联系Hadoop管理员添加写权限");
            }
            else if (errorMsg.contains("CastException") || errorMsg.contains("NumberFormatException")) {
                log.error("=== 数据类型转换错误 ===");
                log.error("解决方案：检查books表的rating字段数据类型");
                log.error("可尝试修改查询中的类型转换逻辑");
            }
            else if (errorMsg.contains("SemanticException")) {
                log.error("=== SQL语义错误 ===");
                log.error("请检查SQL语法和表结构是否匹配");
            }
            else {
                log.error("=== 未知错误类型 ===");
                log.error("错误详情: {}", errorMsg);
            }
        }

        // 生产环境中可添加告警通知
        // alertService.sendAlert("作者汇总表初始化失败: " + e.getMessage());
    }
}